/*
 *	DumpReceiver.java
 *
 *	This file is part of jsresources.org
 */

/*
 * Copyright (c) 1999 - 2001 by Matthias Pfisterer
 * Copyright (c) 2003 by Florian Bomers
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

import	java.io.PrintStream;
import	javax.sound.midi.MidiMessage;
import	javax.sound.midi.ShortMessage;
import	javax.sound.midi.MetaMessage;
import	javax.sound.midi.SysexMessage;
import	javax.sound.midi.Receiver;



/**	Displays the file format information of a MIDI file.
 */
public class DumpReceiver
	implements	Receiver
{

	public static long lastTimeStamp=0;
	public static long timeStamp=0;
	public static long timeDiff;
	
	public static int[][] polyArray = new int[20][3];
	public static boolean polyQueue = false;
	public static int polyPointer = 0;
	
	public static long seByteCount = 0;
	public static long smByteCount = 0;
	public static long seCount = 0;
	public static long smCount = 0;

	private static final String[]		sm_astrKeyNames = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};
	private static final String[]		sm_astrKeySignatures = {"Cb", "Gb", "Db", "Ab", "Eb", "Bb", "F", "C", "G", "D", "A", "E", "B", "F#", "C#"};
//	private static final String[]		SYSTEM_MESSAGE_TEXT =
//	{
//		"System Exclusive (should not be in ShortMessage!)",
//		"MTC Quarter Frame: ",
//		"Song Position: ",
//		"Song Select: ",
//		"Undefined",
//		"Undefined",
//		"Tune Request",
//		"End of SysEx (should not be in ShortMessage!)",
//		"Timing clock",
//		"Undefined",
//		"Start",
//		"Continue",
//		"Stop",
//		"Undefined",
//		"Active Sensing",
//		"System Reset"
//	};
//
//	private static final String[]		QUARTER_FRAME_MESSAGE_TEXT =
//	{
//		"frame count LS: ",
//		"frame count MS: ",
//		"seconds count LS: ",
//		"seconds count MS: ",
//		"minutes count LS: ",
//		"minutes count MS: ",
//		"hours count LS: ",
//		"hours count MS: "
//	};
//
//	private static final String[]		FRAME_TYPE_TEXT =
//	{
//		"24 frames/second",
//		"25 frames/second",
//		"30 frames/second (drop)",
//		"30 frames/second (non-drop)",
//	};
//
//	private PrintStream		m_printStream;
//	private boolean			m_bDebug;
//	private boolean			m_bPrintTimeStampAsTicks;



	public DumpReceiver(PrintStream printStream)
	{
		this(printStream, false);
	}


	public DumpReceiver(PrintStream printStream,
			    boolean bPrintTimeStampAsTicks)
	{
//		m_printStream = printStream;
//		m_bDebug = false;
//		m_bPrintTimeStampAsTicks = bPrintTimeStampAsTicks;
	}

	public void send(MidiMessage message, long lTimeStamp)
	{
		timeStamp = lTimeStamp;

		String	strMessage = null;
		if (message instanceof ShortMessage)
		{
			strMessage = decodeMessage((ShortMessage) message);
		}
		else if (message instanceof SysexMessage)
		{
			strMessage = decodeMessage((SysexMessage) message);
		}
		else if (message instanceof MetaMessage)
		{
			strMessage = decodeMessage((MetaMessage) message);
		}
		else
		{
			strMessage = "unknown message type";
		}
		if (strMessage != null) {
		}
	}
	public void repeatTest() 
	{
		Main.repeated++;
//    	clear the last played notes by entering garbage
    	for (int j=0;j<13;j++){
    		Main.notesArray[Main.notesArrayPointer][0]=j;
        	Main.notesArrayPointer=Main.notesArrayPointer+1;
    	}
    	
		Main.textGUI.textArea.setText("Section = "+Main.section+" \nRepeated "+Main.repeated+" times\nmotifChanges = "+Main.play.motifChanges);

		
		if (Main.section==4&&Main.repeated==4)
		{
			Main.play.gotoSection(5);
			Main.repeated=0;
		}
		if (Main.section==5&&Main.repeated>=2)
		{
			Main.score.endrepeat=true;
//			Main.score.waitMil(Main.quarter*4.);
			Main.play.gotoSection(6);
		}
	}

	public void detectSeq(ShortMessage message) {
		// identifiers: 

//		find 1
		Main.score.missedNote=false;
		if (message.getData1()%12 == 0%12 && Main.notesArrayPointer>2&& !(Main.score.playing1==1&&Main.section==7))
		{
			Main.play.countBeat=0;
			boolean pass = true;
	    	int index=Main.notesArrayPointer-1;
	    	int[] searchArray = {60,64,65,67,65,64,65,67,70,67,65,60,58,60};
	    	for (int i=searchArray.length-2;i>=0;i--)
	    	{
		    		
		    	while (Main.notesArray[index][0]%12==searchArray[i+1]%12&&index>=0)
		    	{
		    		if (i!=searchArray.length-2)
		    		{
		    		Main.play.countBeat=Main.play.countBeat+Main.notesArray[index][2];
		    		}
		    		index=index-1;
		    	}
		    	if (Main.notesArray[index][0]%12==searchArray[i]%12)
		    	{
//		    		System.out.println("------PASS(1): index:"+i+" value:"+searchArray[i]);
		    	}
		    	else {
		    		if (Main.score.missedNote)
		    		{
//		    			System.out.println("------missed note "+Main.notesArray[index][0]+" pc = "+Main.notesArray[index][0]%12+" does NOT = "+searchArray[i+1]%12);
		    			pass = false;
			    		i=-1;
		    		}
		    		else
		    		{
//		    			System.out.println("------missed note "+Main.notesArray[index][0]+" pc = "+Main.notesArray[index][0]%12+" does NOT = "+searchArray[i+1]%12);
		    			Main.score.missedNote=true;
			    		Main.play.countBeat=Main.play.countBeat+Main.notesArray[index][2];
			    		index=index-1;
			    		
		    		}
		    	}
	    	}
	    	if(pass)
	    	{
	    		System.out.println("-------------PASSED!!!!! 1 ");
	    		// repeatTest();
	    		
//	    		find tempo

	    		if (Main.score.playing1!=1)
	    		{
		        	Main.play.melody(1);
	    		}
	    	}
		}

		// find 2
		Main.score.missedNote=false;
		if (message.getData1()%12 == 65%12 && Main.notesArrayPointer>2&& !(Main.score.playing1==2&&Main.section==7))
		{
			Main.play.countBeat=0;
			boolean pass = true;
	    	int index=Main.notesArrayPointer-1;
	    	int[] searchArray = {60,64,60,65,60,67,60,70,72,70,67,65,64,65};
	    	for (int i=searchArray.length-2;i>=0;i--)
	    	{
		    		
		    	while (Main.notesArray[index][0]%12==searchArray[i+1]%12&&index>=0)
		    	{
		    		if (i!=searchArray.length-2)
		    		{
		    		Main.play.countBeat=Main.play.countBeat+Main.notesArray[index][2];
		    		}
		    		index=index-1;
		    	}
		    	if (Main.notesArray[index][0]%12==searchArray[i]%12)
		    	{
//		    		System.out.println("PASS: index:"+i+" value:"+searchArray[i]);
		    	}
		    	else {
		    		if (Main.score.missedNote)
		    		{
			    		pass = false;
			    		i=-1;
		    		}
		    		else
		    		{
		    			Main.score.missedNote=true;
			    		Main.play.countBeat=Main.play.countBeat+Main.notesArray[index][2];
			    		index=index-1;
			    		
		    		}
		    	}
	    	}
	    	if(pass)
	    	{
	    		System.out.println("PASSED!!!!! 2 ");
	    		repeatTest();
	    		
//	    		find tempo

	    		if (Main.score.playing1!=2)
	    		{

	    			System.out.println("Main.score.playing1 "+Main.score.playing1);
		    		Main.play.melody(2);
	    		}
	    	}
		}
		// find 4
		Main.score.missedNote=false;
		if (message.getData1()%12 == 60%12 && Main.notesArrayPointer>2&&!(Main.score.playing1==4&&Main.section==7))
		{
			Main.play.countBeat=0;
			boolean pass = true;
	    	int index=Main.notesArrayPointer-1;
	    	int[] searchArray = {59,55,59,55,57,55,60,62,64,60,55,62,55,60,52,60,55,57,62,60};
	    	for (int i=searchArray.length-2;i>=0;i--)
	    	{
		    		
		    	while (Main.notesArray[index][0]%12==searchArray[i+1]%12&&index>=0)
		    	{
		    		if (i!=searchArray.length-2)
		    		{
		    		Main.play.countBeat=Main.play.countBeat+Main.notesArray[index][2];
		    		}
		    		index=index-1;
		    	}
		    	if (Main.notesArray[index][0]%12==searchArray[i]%12)
		    	{
//		    		System.out.println("PASS: index:"+i+" value:"+searchArray[i]);
		    	}
		    	else {
		    		if (Main.score.missedNote)
		    		{
		    			
			    		pass = false;
			    		i=-1;
		    		}
		    		else
		    		{
		    			Main.score.missedNote=true;
			    		Main.play.countBeat=Main.play.countBeat+Main.notesArray[index][2];
			    		index=index-1;
			    		
		    		}
		    	}
	    	}
	    	if(pass)
	    	{
	    		System.out.println("PASSED!!!!! 4 ");
	    		// repeatTest();	        	
//	    		find tempo
	    		if (Main.score.playing1!=4)
	    		{

		    		Main.play.melody(4);

	    		}
	    	}
		}
		
		// find 9
		Main.score.missedNote=false;
		if (message.getData1()%12 == 75%12 && Main.notesArrayPointer>2&&!(Main.score.playing1==9&&Main.section==7))
		{
			Main.play.countBeat=0;
			boolean pass = true;
	    	int index=Main.notesArrayPointer-1;
	    	int[] searchArray = {60,63,65,67,66,60,63,65,70,72,63,65,66,72,70,75};
	    	for (int i=searchArray.length-2;i>=0;i--)
	    	{
		    		
		    	while (Main.notesArray[index][0]%12==searchArray[i+1]%12&&index>=0)
		    	{
		    		if (i!=searchArray.length-2)
		    		{
		    		Main.play.countBeat=Main.play.countBeat+Main.notesArray[index][2];
		    		}
		    		index=index-1;
		    	}
		    	if (Main.notesArray[index][0]%12==searchArray[i]%12)
		    	{
//		    		System.out.println("PASS: index:"+i+" value:"+searchArray[i]);
		    	}
		    	else {
		    		if (Main.score.missedNote)
		    		{
			    		pass = false;
//			    		System.out.println("FAIL: value:"+searchArray[i]);
			    		i=-1;
		    		}
		    		else
		    		{
		    			Main.score.missedNote=true;
//			    		System.out.println("FAIL(first time): value:"+searchArray[i]);
			    		Main.play.countBeat=Main.play.countBeat+Main.notesArray[index][2];
			    		index=index-1;
			    		
		    		}
		    	}
	    	}
	    	if(pass)
	    	{
	    		System.out.println("PASSED!!!!! 9 ");
	    		// repeatTest();
//	    		find tempo
	    		if (Main.score.playing1!=9)
	    		{

		    		Main.play.melody(9);
	    		}
	    	}
		}
		
		// find 11
		Main.score.missedNote=false;
		if (message.getData1()%12 == 0%12 && Main.notesArrayPointer>2&&!(Main.score.playing1==11&&Main.section==7))
		{
			Main.play.countBeat=0;
			boolean pass = true;
	    	int index=Main.notesArrayPointer-1;
	    	int[] searchArray = {6,11,0,6,10,11,0,11,7,0};
	    	for (int i=searchArray.length-2;i>=0;i--)
	    	{
		    		
		    	while (Main.notesArray[index][0]%12==searchArray[i+1]%12&&index>=0)
		    	{
		    		if (i!=searchArray.length-2)
		    		{
		    		Main.play.countBeat=Main.play.countBeat+Main.notesArray[index][2];
		    		}
		    		index=index-1;
		    	}
		    	if (Main.notesArray[index][0]%12==searchArray[i]%12)
		    	{
//		    		System.out.println("PASS: index:"+i+" value:"+searchArray[i]);
		    	}
		    	else {
		    		if (Main.score.missedNote)
		    		{
			    		pass = false;
//			    		System.out.println("FAIL: value:"+searchArray[i]);
			    		i=-1;
		    		}
		    		else
		    		{
		    			Main.score.missedNote=true;
//			    		System.out.println("FAIL(first time): value:"+searchArray[i]);
			    		Main.play.countBeat=Main.play.countBeat+Main.notesArray[index][2];
			    		index=index-1;
			    		
		    		}
		    	}
	    	}
	    	if(pass)
	    	{
	    		System.out.println("PASSED!!!!! 11 ");
	    		// repeatTest();
//	    		find tempo
	    		if (Main.score.playing1!=11)
	    		{

		    		Main.play.melody(11);
	    		}
	    	}
		}

		// find 13
		Main.score.missedNote=false;
		if (message.getData1()%12 == 2%12 && Main.notesArrayPointer>2&& !(Main.score.playing1==13&&Main.section==7))
		{
			Main.play.countBeat=0;
			boolean pass = true;
	    	int index=Main.notesArrayPointer-1;
	    	int[] searchArray = {7,11,3,6,7,11,3,6,5,2};
	    	for (int i=searchArray.length-2;i>=0;i--)
	    	{
		    		
		    	while (Main.notesArray[index][0]%12==searchArray[i+1]%12&&index>=0)
		    	{
		    		if (i!=searchArray.length-2)
		    		{
		    		Main.play.countBeat=Main.play.countBeat+Main.notesArray[index][2];
		    		}
		    		index=index-1;
		    	}
		    	if (Main.notesArray[index][0]%12==searchArray[i]%12)
		    	{
//		    		System.out.println("PASS: index:"+i+" value:"+searchArray[i]);
		    	}
		    	else {
		    		if (Main.score.missedNote)
		    		{
			    		pass = false;
//			    		System.out.println("FAIL: value:"+searchArray[i]);
			    		i=-1;
		    		}
		    		else
		    		{
		    			Main.score.missedNote=true;
//			    		System.out.println("FAIL(first time): value:"+searchArray[i]);
			    		Main.play.countBeat=Main.play.countBeat+Main.notesArray[index][2];
			    		index=index-1;
			    		
		    		}
		    	}
	    	}
	    	if(pass)
	    	{
	    		System.out.println("PASSED!!!!! 13 ");
	    		// repeatTest();
//	    		find tempo
	    		if (Main.score.playing1!=13)
	    		{

		    		Main.play.melody(13);
	    		}
	    	}
		}
		// find 14
		Main.score.missedNote=false;
		if (message.getData1()%12 == 49%12 && Main.notesArrayPointer>2&& Main.score.playing0!=14)
		{
			Main.play.countBeat=0;
			boolean pass = true;
			if (message.getData1()>0)
			{
		    	int index=Main.notesArrayPointer-1;
		    	int[] searchArray = {48,51,50,49};
		    	for (int i=searchArray.length-2;i>=0;i--)
		    	{
			    		
			    	while (Main.notesArray[index][0]%12==searchArray[i+1]%12&&index>=0)
			    	{
			    		if (i!=searchArray.length-2)
			    		{
			    		Main.play.countBeat=Main.play.countBeat+Main.notesArray[index][2];
			    		}
			    		index=index-1;
			    	}
			    	if (Main.notesArray[index][0]%12==searchArray[i]%12)
			    	{
	//		    		System.out.println("PASS: index:"+i+" value:"+searchArray[i]);
			    	}
			    	else {
	
				    		pass = false;
				    		i=-1;
	
			    	}
		    	}
			}
	    	if(pass)
	    	{
	    		System.out.println("PASSED!!! 14  !!!!!");
//	    		repeatTest();
	        	for (int j=0;j<13;j++){
	        		System.out.println("!!!!clearing!!!!!!!!!!!!!!!!!!!!");
	        		Main.notesArray[Main.notesArrayPointer][0]=j;
	            	Main.notesArrayPointer=Main.notesArrayPointer+1;
	        		Main.notesArray_bass[Main.notesArrayPointer_bass][0]=j;
	            	Main.notesArrayPointer_bass=Main.notesArrayPointer_bass+1;
	        	}
//	    		find tempo
	    		if (Main.score.playing0!=14)
	    		{
		    		System.out.println("PASSED!!! 14_2!  !!!!!");
	    			Main.score.clearScheduler(0);
	    			Main.score.playing0=14;
		        	Main.play.melody(14);
	    		}
	    	}
		}
		// find 15
		Main.score.missedNote=false;
		if (message.getData1()%12 == 7%12 && Main.notesArrayPointer>2&& Main.score.playing0!=15)
		{
			Main.play.countBeat=0;
			boolean pass = true;
	    	if (Main.section!=7&&message.getData1()>0)
	    	{	
		    	int index=Main.notesArrayPointer-1;
		    	int[] searchArray = {0,10,0,5,6,7};
		    	for (int i=searchArray.length-2;i>=0;i--)
		    	{
			    	while (Main.notesArray[index][0]%12==searchArray[i+1]%12&&index>=0)
			    	{
			    		if (i!=searchArray.length-2)
			    		{
			    		Main.play.countBeat=Main.play.countBeat+Main.notesArray[index][2];
			    		}
			    		index=index-1;
			    	}
			    	if (Main.notesArray[index][0]%12==searchArray[i]%12)
			    	{
	//		    		System.out.println("PASS: index:"+i+" value:"+searchArray[i]);
			    	}
			    	else {
			    		if (Main.score.missedNote)
			    		{
				    		pass = false;
	//			    		System.out.println("FAIL: value:"+searchArray[i]);
				    		i=-1;
			    		}
			    		else
			    		{
			    			Main.score.missedNote=true;
	//			    		System.out.println("FAIL(first time): value:"+searchArray[i]);
				    		Main.play.countBeat=Main.play.countBeat+Main.notesArray[index][2];
				    		index=index-1;
				    		
			    		}
			    	}
			    	while (Main.notesArray[index][0]%12==searchArray[i+1]%12&&index>=0)
			    	{
			    		if (i!=searchArray.length-2)
			    		{
			    		Main.play.countBeat=Main.play.countBeat+Main.notesArray[index][2];
			    		}
			    		index=index-1;
			    	}
			    	if (Main.notesArray[index][0]%12==searchArray[i]%12)
			    	{
	//		    		System.out.println("PASS: index:"+i+" value:"+searchArray[i]);
			    	}
			    	else {
			    		if (Main.score.missedNote)
			    		{
				    		pass = false;
	//			    		System.out.println("FAIL: value:"+searchArray[i]);
				    		i=-1;
			    		}
			    		else
			    		{
			    			Main.score.missedNote=true;
	//			    		System.out.println("FAIL(first time): value:"+searchArray[i]);
				    		Main.play.countBeat=Main.play.countBeat+Main.notesArray[index][2];
				    		index=index-1;
				    		
			    		}
			    	}
		    	}
	    	}
	    	
	    	if(pass)
	    	{
	    		System.out.println("PASSED!!!!! 15");
//	        	clear the last played notes by entering garbage
	        	for (int j=0;j<13;j++){
	        		System.out.println("!!!!clearing!!!!!!!!!!!!!!!!!!!!");
	        		Main.notesArray[Main.notesArrayPointer][0]=j;
	            	Main.notesArrayPointer=Main.notesArrayPointer+1;
	        		Main.notesArray_bass[Main.notesArrayPointer_bass][0]=j;
	            	Main.notesArrayPointer_bass=Main.notesArrayPointer_bass+1;
	        	}
//	    		repeatTest();
//	    		find tempo
	    		if (Main.score.playing0!=15)
	    		{
    			Main.score.clearScheduler(0);
    			Main.score.playing0=15;
		    		Main.play.melody(15);
	    		}
	    	}
		}
		
		// find 16
		Main.score.missedNote=false;
		if (message.getData1()%12 == 0%12 && Main.notesArrayPointer>2&& Main.score.playing0!=16 )
		{
			Main.play.countBeat=0;
			boolean pass = true;
			if (message.getData1()>0)
			{
				int index=Main.notesArrayPointer-1;
		    	int[] searchArray = {10,8,7,5,4,7,1,0};
		    	for (int i=searchArray.length-2;i>=0;i--)
		    	{
			    		
			    	while (Main.notesArray[index][0]%12==searchArray[i+1]%12&&index>=0)
			    	{
			    		if (i!=searchArray.length-2)
			    		{
			    		Main.play.countBeat=Main.play.countBeat+Main.notesArray[index][2];
			    		}
			    		index=index-1;
			    	}
			    	if (Main.notesArray[index][0]%12==searchArray[i]%12)
			    	{
	//		    		System.out.println("PASS: index:"+i+" value:"+searchArray[i]);
			    	}
			    	else {
			    		if (Main.score.missedNote)
			    		{
			    			
				    		pass = false;
				    		i=-1;
			    		}
			    		else
			    		{
			    			Main.score.missedNote=true;
				    		Main.play.countBeat=Main.play.countBeat+Main.notesArray[index][2];
				    		index=index-1;
				    		
			    		}
			    	}
		    	}
		    	
		    	if(pass)
		    	{
		    		System.out.println("PASSED!!!!! 16");
//		        	clear the last played notes by entering garbage
		        	for (int j=0;j<13;j++){
		        		System.out.println("!!!!clearing!!!!!!!!!!!!!!!!!!!!");
		        		Main.notesArray[Main.notesArrayPointer][0]=j;
		            	Main.notesArrayPointer=Main.notesArrayPointer+1;
		        		Main.notesArray_bass[Main.notesArrayPointer_bass][0]=j;
		            	Main.notesArrayPointer_bass=Main.notesArrayPointer_bass+1;
		        	}
//		    		repeatTest();
	//	    		find tempo
		    		if (Main.score.playing1!=16)
		    		{
		    			Main.score.playing0=16;
		    			Main.score.clearScheduler(0);
			    		Main.play.melody(16);
		    		}
		    	}
			}
		}

	}
	
	
	public String decodeMessage(ShortMessage message)
	{

		String	strMessage = null;

		switch (message.getCommand())
		{
		case 0x80://note off

			break;

		case 0x90://note on
//			if (Main.score.playing0==14)
//			{
//				if (Main.arm[1]!=55)
//				{
//					Main.score.noteOut(55,0,1);
//				}
//			}
			if (Main.wait&&message.getData2()>0)
			{
				Main.wait=false;
			}
			
			if (message.getData2()>0)
			{
			}
			
			if (!Main.firstNote)
			{
				Main.firstNote=true;
				stop();
				System.out.println("FIRST NOTE");
				PositionArms pos = new PositionArms();
				Thread posThread = new Thread(pos);
				posThread.start();
////				run Entrance Thread
//				EntranceDetection entrance = new EntranceDetection();
//				Thread entranceThread = new Thread(entrance);
//				entranceThread.start();
				
			}

			if (message.getData2()>0){
				Main.velocity = (int)((message.getData2()));
				if (message.getData1()>0)
				{
					timeDiff = (timeStamp - lastTimeStamp)/1000;
					lastTimeStamp = timeStamp;	
					
					int[] note = {message.getData1(),message.getData2(), (int) timeDiff};
					Main.notesArray[Main.notesArrayPointer][0]=note[0];
					Main.notesArray[Main.notesArrayPointer][1]=note[1];
					Main.notesArray[Main.notesArrayPointer][2]=note[2];
					Main.notesArrayPointer=Main.notesArrayPointer+1;
					System.out.println("treble note: "+message.getData1()+" Main.velocity="+Main.velocity);
				}
			}
			detectSeq(message);
			break;

		case 0xa0:
			strMessage = "polyphonic key pressure " + getKeyName(message.getData1()) + " pressure: " + message.getData2();
			break;

		case 0xb0:
			strMessage = "control change " + message.getData1() + " value: " + message.getData2();
			break;

		case 0xc0:
			strMessage = "program change " + message.getData1();
			break;

		case 0xd0:
			strMessage = "key pressure " + getKeyName(message.getData1()) + " pressure: " + message.getData2();
			break;

		case 0xe0:
			strMessage = "pitch wheel change " + get14bitValue(message.getData1(), message.getData2());
			break;

		case 0xF0:
			strMessage = null;

			break;


		default:
			strMessage = null;
//			strMessage = "unknown message: status = " + message.getStatus() + ", byte1 = " + message.getData1() + ", byte2 = " + message.getData2();
			break;
		}
		if (message.getCommand() != 0xF0)
		{
//			int	nChannel = message.getChannel() + 1;
//			String	strChannel = "channel " + nChannel + ": ";
//			strMessage = strChannel + strMessage;
		}
		smCount++;
		smByteCount+=message.getLength();
//		return "["+getHexString(message)+"] "+strMessage;
		return strMessage;
	}



	public String decodeMessage(SysexMessage message)
	{
		byte[]	abData = message.getData();
		String	strMessage = null;
		// System.out.println("sysex status: " + message.getStatus());
		if (message.getStatus() == SysexMessage.SYSTEM_EXCLUSIVE)
		{
			strMessage = "Sysex message: F0" + getHexString(abData);
		}
		else if (message.getStatus() == SysexMessage.SPECIAL_SYSTEM_EXCLUSIVE)
		{
			strMessage = "Continued Sysex message F7" + getHexString(abData);
			seByteCount--; // do not count the F7
		}
		seByteCount += abData.length + 1;
		seCount++; // for the status byte
		return strMessage;
	}



	public String decodeMessage(MetaMessage message)
	{
		byte[]	abData = message.getData();
		String	strMessage = null;
		// System.out.println("data array length: " + abData.length);
		switch (message.getType())
		{
		case 0:
			int	nSequenceNumber = ((abData[0] & 0xFF) << 8) | (abData[1] & 0xFF);
			strMessage = "Sequence Number: " + nSequenceNumber;
			break;

		case 1:
			String	strText = new String(abData);
			strMessage = "Text Event: " + strText;
			break;

		case 2:
			String	strCopyrightText = new String(abData);
			strMessage = "Copyright Notice: " + strCopyrightText;
			break;

		case 3:
			String	strTrackName = new String(abData);
			strMessage = "Sequence/Track Name: " +  strTrackName;
			break;

		case 4:
			String	strInstrumentName = new String(abData);
			strMessage = "Instrument Name: " + strInstrumentName;
			break;

		case 5:
			String	strLyrics = new String(abData);
			strMessage = "Lyric: " + strLyrics;
			break;

		case 6:
			String	strMarkerText = new String(abData);
			strMessage = "Marker: " + strMarkerText;
			break;

		case 7:
			String	strCuePointText = new String(abData);
			strMessage = "Cue Point: " + strCuePointText;
			break;

		case 0x20:
			int	nChannelPrefix = abData[0] & 0xFF;
			strMessage = "MIDI Channel Prefix: " + nChannelPrefix;
			break;

		case 0x2F:
			strMessage = "End of Track";
			break;

		case 0x51:
			int	nTempo = ((abData[0] & 0xFF) << 16)
					| ((abData[1] & 0xFF) << 8)
					| (abData[2] & 0xFF);           // tempo in microseconds per beat
			float bpm = convertTempo(nTempo);
			// truncate it to 2 digits after dot
			bpm = (float) (Math.round(bpm*100.0f)/100.0f);
			strMessage = "Set Tempo: "+bpm+" bpm";
			break;

		case 0x54:
			// System.out.println("data array length: " + abData.length);
			strMessage = "SMTPE Offset: "
				+ (abData[0] & 0xFF) + ":"
				+ (abData[1] & 0xFF) + ":"
				+ (abData[2] & 0xFF) + "."
				+ (abData[3] & 0xFF) + "."
				+ (abData[4] & 0xFF);
			break;

		case 0x58:
			strMessage = "Time Signature: "
				+ (abData[0] & 0xFF) + "/" + (1 << (abData[1] & 0xFF))
				+ ", MIDI clocks per metronome tick: " + (abData[2] & 0xFF)
				+ ", 1/32 per 24 MIDI clocks: " + (abData[3] & 0xFF);
			break;

		case 0x59:
			String	strGender = (abData[1] == 1) ? "minor" : "major";
			strMessage = "Key Signature: " + sm_astrKeySignatures[abData[0] + 7] + " " + strGender;
			break;

		case 0x7F:
			// TODO: decode vendor code, dump data in rows
			String	strDataDump = getHexString(abData);
			strMessage = "Sequencer-Specific Meta event: " + strDataDump;
			break;

		default:
			String	strUnknownDump = getHexString(abData);
			strMessage = "unknown Meta event: " + strUnknownDump;
			break;

		}
		return strMessage;
	}



	public static String getKeyName(int nKeyNumber)
	{
		if (nKeyNumber > 127)
		{
			return "illegal value";
		}
		else
		{
			int	nNote = nKeyNumber % 12;
			int	nOctave = nKeyNumber / 12;
			return sm_astrKeyNames[nNote] + (nOctave - 1);
		}
	}


	public static int get14bitValue(int nLowerPart, int nHigherPart)
	{
		return (nLowerPart & 0x7F) | ((nHigherPart & 0x7F) << 7);
	}




	// convert from microseconds per quarter note to beats per minute and vice versa
	private static float convertTempo(float value) {
		if (value <= 0) {
			value = 0.1f;
		}
		return 60000000.0f / value;
	}



	private static char hexDigits[] = 
	   {'0', '1', '2', '3', 
	    '4', '5', '6', '7', 
	    '8', '9', 'A', 'B', 
	    'C', 'D', 'E', 'F'};

	public static String getHexString(byte[] aByte)
	{
		StringBuffer	sbuf = new StringBuffer(aByte.length * 3 + 2);
		for (int i = 0; i < aByte.length; i++)
		{
			sbuf.append(' ');
			sbuf.append(hexDigits[(aByte[i] & 0xF0) >> 4]);
			sbuf.append(hexDigits[aByte[i] & 0x0F]);
			/*byte	bhigh = (byte) ((aByte[i] &  0xf0) >> 4);
			sbuf.append((char) (bhigh > 9 ? bhigh + 'A' - 10: bhigh + '0'));
			byte	blow = (byte) (aByte[i] & 0x0f);
			sbuf.append((char) (blow > 9 ? blow + 'A' - 10: blow + '0'));*/
		}
		return new String(sbuf);
	}
	
	private static String intToHex(int i) {
		return ""+hexDigits[(i & 0xF0) >> 4]
		         +hexDigits[i & 0x0F];
	}

	public static String getHexString(ShortMessage sm)
	{
		// bug in J2SDK 1.4.1
		// return getHexString(sm.getMessage());
		int status = sm.getStatus();
		String res = intToHex(sm.getStatus());
		// if one-byte message, return
		switch (status) {
			case 0xF6:			// Tune Request
			case 0xF7:			// EOX
	    		// System real-time messages
			case 0xF8:			// Timing Clock
			case 0xF9:			// Undefined
			case 0xFA:			// Start
			case 0xFB:			// Continue
			case 0xFC:			// Stop
			case 0xFD:			// Undefined
			case 0xFE:			// Active Sensing
			case 0xFF: return res;
		}
		res += ' '+intToHex(sm.getData1());
		// if 2-byte message, return
		switch (status) {
			case 0xF1:			// MTC Quarter Frame
			case 0xF3:			// Song Select
					return res;
		}
		switch (sm.getCommand()) {
			case 0xC0:
			case 0xD0:
					return res;
		}
		// 3-byte messages left
		res += ' '+intToHex(sm.getData2());
		return res;
	}


	public void close() {
		// TODO Auto-generated method stub
		
	}
	public void stop() {
		StopVision stop = new StopVision();
		Thread thread2 = new Thread(stop);
		thread2.start();
	}
}





/*** DumpReceiver.java ***/
